//
//  HlyricsParser.m
//  HMusicPlayer
//
//  Created by Hament on 14/9/22.
//  Copyright (c) 2014年 HJ. All rights reserved.
//

#import "HlyricsParser.h"
#import "HCoreConfig.h"
#import "HLyricItem.h"
#import "GTMNSData+zlib.h"


#define songlyricReg @"\\[(\\d{2}:\\d{2}\\.\\d{2})\\]"

#define songkrcTimeReg @"\\[(\\d{0,8},\\d{0,8})\\]"



@implementation HlyricsParser








//根据本地文件解析歌词
+(void)parserLRCFileWithLocalPath:(NSString*)localpath
                         reqMainQueue:(BOOL)mainQueue
                  subTheadfinisHandel:(void(^)(BOOL,BOOL, NSArray * lyricArr))finish{

//localpath 应该外面判断是否存在

    NSString * ext=[HCoreConfig numberToString:[localpath pathExtension]];
    ext=ext.lowercaseString;

//    if ([ext isEqualToString:@""]==YES) {
//       
//        //告诉用户无法识别的后缀名文件
//        if (mainQueue) {
//            dispatch_async(dispatch_get_main_queue(),^{
//                finish(NO,nil);
//            });
//        } else {
//           finish(NO,nil);
//        }
//
//        return;
//    }
//    //lrc处理
//    else
    
    //不是krc的当lrc处理
    if (![ext isEqualToString:@"krc"]) {
    
        
        NSStringEncoding enc=NSUTF8StringEncoding;// =NSUTF8StringEncoding;//kCFStringEncodingGB_18030_2000
        
        NSString * content=[NSString stringWithContentsOfFile:localpath encoding:enc error:nil];

         //debugLog(@"enc:%d content：%@ \n---------",enc,content);
        
        /*
        NSString * content=[[NSString alloc] initWithData:data encoding:enc];
        debugLog(@"enc:%d content：%@ \n---------",enc,content);
        */
        
        //utf8不行的话就gb18030
        if (!content || [content isKindOfClass:[NSNull class]]) {
            enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
            content=[NSString stringWithContentsOfFile:localpath encoding:enc error:nil];
            
        }

        
      NSArray *arr=[HlyricsParser parserWithLrcStr:CHECKSTR(content)];
        BOOL hastimeline=YES;
        //如果歌词少于5行,可以看作没有时间轴
        if(arr.count<5){
        
            arr=[HlyricsParser parserWithLrcStrWithOutTimeline:CHECKSTR(content)];
            hastimeline=NO;
        }
        
        
        
        
        BOOL hasData=NO;
        if (arr) {
            hasData=YES;

        }
        
        //根据主线程
        if (mainQueue) {
            dispatch_async(dispatch_get_main_queue(),^{
                finish(hasData,hastimeline,arr);
            });
        } else {
            finish(hasData,hastimeline,arr);
        }
        
        
        //debugLog(@"content:\n%@",content);
        
        
    }
    //krc
    else {
    
        NSString * krccontent=CHECKSTR([HlyricsParser KRCDecode:localpath]);
       
        NSArray *arr=[HlyricsParser parserWithKrcStr:krccontent];
        
        BOOL hasData=NO;
        if (arr) {
            hasData=YES;
        }
        
        //根据主线程
        if (mainQueue) {
            dispatch_async(dispatch_get_main_queue(),^{
                finish(hasData,YES,arr);
            });
        } else {
            finish(hasData,YES,arr);
        }

      
    }
//    else {
//    
//        //告诉用户暂时只支持krc或lrc文件
//        
//        if (mainQueue) {
//            dispatch_async(dispatch_get_main_queue(),^{
//                finish(NO,nil);
//            });
//        } else {
//            finish(NO,nil);
//        }
//    
//    }



}

#pragma 把lrc转化为数组,处理整个lyrics文本
+(NSMutableArray*)parserWithLrcStr:(NSString*)lrcstr{
    
    if ([lrcstr isEqualToString:@""]) {
        return nil;
    }
   // debugLog(@"%@ \n---------",lrcstr);
    NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:songlyricReg
                                                                            options:0
                                                                              error:NULL];
    NSCharacterSet * cset=[NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSCharacterSet * dset=[NSCharacterSet characterSetWithCharactersInString:@"[]"];
    
    
    NSMutableArray * arr=[NSMutableArray arrayWithCapacity:10];//all
    NSMutableArray * songlyarr=[NSMutableArray arrayWithCapacity:10];//just put 有时间的部分
    
    //由于字符编码或软件编辑的问题，会存在/r /n 转换的问题
    
    //分割判断的时候使用\n的
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\r\n" replaceWith:@"\n"];
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\n\r" replaceWith:@"\n"];
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\r" replaceWith:@"\n"];
    
    
    NSArray * tempArray=[lrcstr componentsSeparatedByString:@"\n"];
    
    for (NSString * nstr in tempArray)
    {
        if (nstr && nstr.length > 0)
        {
            NSString * str=[nstr stringByTrimmingCharactersInSet:cset];
            
            if ([str hasPrefix:@"[ti:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Song",nil),CHECKSTR(title)];
                [arr addObject:litem];
                
            } else if ([str hasPrefix:@"[ar:"]) {
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Artist",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }else if ([str hasPrefix:@"[al:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Album",nil),CHECKSTR(title)];
                [arr addObject:litem];
            } else if ([str hasPrefix:@"[au:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Lyrics Composer",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }
            else if ([str hasPrefix:@"[by:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"By",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }
            
            //获取带时间的歌词
            else {
                
                
                NSArray *matches = [regex matchesInString:str options:0 range:NSMakeRange(0, [str length])];
                
                NSString * lystr= [regex stringByReplacingMatchesInString:str options:0 range:NSMakeRange(0, [str length]) withTemplate:@""];
                
                
                
                for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
                    
                    
                    NSString * timestr = [[str substringWithRange:match.range] stringByTrimmingCharactersInSet:dset]; //<ID>
                    
                    //转化为毫秒
                    NSArray * timearr=[timestr componentsSeparatedByString:@":"];
                    NSString * min=timearr[0];
                    
                    NSArray * stimeArr=[timearr[1] componentsSeparatedByString:@"."];
                    NSString * second=stimeArr[0];
                    NSString * mill=stimeArr[1];
                    
                    HLyricItem * litem=[[HLyricItem alloc] init];
                    litem.beginDuration=min.intValue*60*1000+second.intValue*1000+mill.intValue*10;
                    litem.contentStr=CHECKSTR(lystr);
                    
                    [songlyarr addObject:litem];
                    
                    
                    //debugLog(@"duration:%d,item:%@,str:%@",litem.beginDuration,litem.contentStr,str);
                }
                
            }
            
            
            
        }
        
    }
    
    
    
    
    //排序
    NSArray * sortSonglyarr = [songlyarr sortedArrayUsingComparator:^(HLyricItem * obj1 ,HLyricItem* obj2) {
        if (obj1.beginDuration > obj2.beginDuration)
            return NSOrderedDescending;
        else
            return NSOrderedAscending;
        return NSOrderedSame;
    }];
    
    
    
    [arr addObjectsFromArray:sortSonglyarr];
    
    //    for (HLyricItem *item in arr) {
    //        debugLog(@"duration:%f,item:%@",item.beginDuration,item.contentStr);
    //    }
    
    
    //清空一下最后多余的空行
    int lcount=(int)[arr count];
    if (lcount>0) {
        NSMutableIndexSet * indexset=[NSMutableIndexSet indexSet];
        for (int i=(lcount-1); i>0; i--) {
            HLyricItem * litem=arr[i];
            if ([litem.contentStr isEqualToString:@""]) {
                [indexset addIndex:i];
                
            } else {
            
                break;
            }

        }
        
        if (indexset.count>0) {
            [arr removeObjectsAtIndexes:indexset];
        }
        
        
    }
    
    
    return arr;
}




#pragma 处理没有timeline的整个lyrics文本
+(NSArray*)parserWithLrcStrWithOutTimeline:(NSString*)lrcstr{
    
    if ([lrcstr isEqualToString:@""]) {
        return nil;
    }
    // debugLog(@"%@ \n---------",lrcstr);

    NSCharacterSet * cset=[NSCharacterSet whitespaceAndNewlineCharacterSet];

    //由于字符编码或软件编辑的问题，会存在/r /n 转换的问题
    
    //分割判断的时候使用\n的
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\r\n" replaceWith:@"\n"];
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\n\r" replaceWith:@"\n"];
    lrcstr=[HCoreConfig ReplaceFirstNewLine:lrcstr symbol:@"\r" replaceWith:@"\n"];
    
    
    NSArray * tempArray=[lrcstr componentsSeparatedByString:@"\n"];
    NSMutableArray * lyricArr=[NSMutableArray array];
    
    for (NSString * nstr in tempArray)
    {
        NSString * str=[nstr stringByTrimmingCharactersInSet:cset];

        if (str.length > 0)
        {

            HLyricItem * litem=[[HLyricItem alloc] init];
            litem.beginDuration=InvalidSoundDuration;
            litem.contentStr=CHECKSTR(str);
            [lyricArr addObject:litem];
        
        }
        
    }

    
    
//    //清空一下最后多余的空行
//    int lcount=(int)[arr count];
//    if (lcount>0) {
//        NSMutableIndexSet * indexset=[NSMutableIndexSet indexSet];
//        for (int i=(lcount-1); i>0; i--) {
//            HLyricItem * litem=arr[i];
//            if ([litem.contentStr isEqualToString:@""]) {
//                [indexset addIndex:i];
//                
//            } else {
//                
//                break;
//            }
//            
//        }
//        
//        if (indexset.count>0) {
//            [arr removeObjectsAtIndexes:indexset];
//        }
//        
//        
//    }
    
    if (lyricArr.count==0) {
        return nil;
    }
    
    
    return lyricArr;
}




#pragma krcDecode
//异或加密 密钥
+ (NSString *) KRCDecode: (NSString * )filePath{


    NSString * EncKey = @"@Gaw^2tGQ61-ÎÒni";
    //char EncKey[] = { '@', 'G', 'a', 'w', '^', '2', 't', 'G', 'Q', '6', '1', '-', 'Î', 'Ò', 'n', 'i' };
    
    NSData * totalBytes = [[NSMutableData alloc] initWithContentsOfFile:filePath];
    // HeadBytes = [[NSMutableData alloc] initWithData:[totalBytes subdataWithRange:NSMakeRange(0, 4)]];
  NSMutableData*  EncodedBytes = [[NSMutableData alloc] initWithData:[totalBytes subdataWithRange:NSMakeRange(4, totalBytes.length - 4)]];
    
  NSMutableData*  ZipBytes = [[NSMutableData alloc] initWithCapacity:EncodedBytes.length];
    
    Byte * encodedBytes = EncodedBytes.mutableBytes;
    
    NSUInteger EncodedBytesLength = EncodedBytes.length;
    
    for (int i = 0; i < EncodedBytesLength; i++)
    {
        int l = i % 16;
        char c = [EncKey characterAtIndex:l];
        
        Byte b = (Byte)((encodedBytes[i]) ^ c);
        
        [ZipBytes appendBytes:&b length:1];
        
    }
    //
    
    //EncodedBytes=[HeadBytes appendBytes:EncodedBytes length:EncodedBytes.length];
    //NSMutableData * thedata=[[NSMutableData alloc] initWithData:<#(NSData *)#>];
    
   NSData* UnzipBytes = [NSData gtm_dataByInflatingData:ZipBytes];
    
    
    NSStringEncoding enc =NSUTF8StringEncoding;
    
    NSString * s = [[NSString alloc] initWithData:UnzipBytes encoding:enc];
    
    if (!s) {
        //utf8不行的话就gb18030
        if (!s || [s isKindOfClass:[NSNull class]]) {
            enc = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingGB_18030_2000);
            s = [[NSString alloc] initWithData:UnzipBytes encoding:enc];
        }
        
    }
    return s;


}


#pragma 把krc转化为数组,处理整个lyrics文本
+(NSMutableArray*)parserWithKrcStr:(NSString*)lrcstr{

    if ([lrcstr isEqualToString:@""]) {
        return nil;
    }
//debugLog(@"%@ \n---------",lrcstr);
    NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:songkrcTimeReg
                                                                                    options:0
                                                                                      error:NULL];
    NSCharacterSet * cset=[NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSCharacterSet * dset=[NSCharacterSet characterSetWithCharactersInString:@"[]"];
    
    
    NSMutableArray * arr=[NSMutableArray arrayWithCapacity:10];//all
    NSMutableArray * songlyarr=[NSMutableArray arrayWithCapacity:10];//just put 有时间的部分
    
     NSArray * tempArray=[lrcstr componentsSeparatedByString:@"\n"];
    
    for (NSString * nstr in tempArray)
    {
        if (nstr && nstr.length > 0)
        {
           NSString * str=[nstr stringByTrimmingCharactersInSet:cset];

            if ([str hasPrefix:@"[ti:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Song",nil),CHECKSTR(title)];
                [arr addObject:litem];
                
            } else if ([str hasPrefix:@"[ar:"]) {
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Artist",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }else if ([str hasPrefix:@"[al:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Album",nil),CHECKSTR(title)];
                [arr addObject:litem];
            } else if ([str hasPrefix:@"[au:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"Lyrics Composer",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }
            else if ([str hasPrefix:@"[by:"]) {
                
                NSString * title=[str substringWithRange:NSMakeRange(4, str.length-5)];
                HLyricItem * litem=[[HLyricItem alloc] init];
                litem.beginDuration=0;
                litem.contentStr=[NSString stringWithFormat:@"%@:%@",NSLocalizedString(@"By",nil),CHECKSTR(title)];
                [arr addObject:litem];
            }
            
            //获取带时间的歌词
            else {

                
                
                NSArray *matches = [regex matchesInString:str options:0 range:NSMakeRange(0, [str length])];
                
                NSString * lystr= [regex stringByReplacingMatchesInString:str options:0 range:NSMakeRange(0, [str length]) withTemplate:@""];
                
                NSString * noTimeStr=[HCoreConfig stringByStrippingHTML:lystr];//去除<>

                
                for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
                    
                    
                    NSString * timestr = [[str substringWithRange:match.range] stringByTrimmingCharactersInSet:dset]; //<ID>
                    
                    //获取毫秒
                    NSArray * timearr=[timestr componentsSeparatedByString:@","];
                    NSString * millseconds=timearr[0];

                    
                    HLyricItem * litem=[[HLyricItem alloc] init];
                    litem.beginDuration=millseconds.integerValue;
                    litem.contentStr=CHECKSTR(noTimeStr);
                    
                    [songlyarr addObject:litem];
                    
                    
                    //debugLog(@"duration:%f,item:%@",litem.beginDuration,litem.contentStr);
                }
                
            }
            
            
            
     }
   
    }
    
    
    
    
    //排序
   NSArray * sortSonglyarr = [songlyarr sortedArrayUsingComparator:^(HLyricItem * obj1 ,HLyricItem* obj2) {
        if (obj1.beginDuration > obj2.beginDuration)
            return NSOrderedDescending;
        else
            return NSOrderedAscending;
        return NSOrderedSame;
    }];
    
    
    
    [arr addObjectsFromArray:sortSonglyarr];
    
//    for (HLyricItem *item in arr) {
//        debugLog(@"duration:%f,item:%@",item.beginDuration,item.contentStr);
//    }
    
    return arr;
}










@end
